package com.wangshaoyu.music_player.controller;

import com.wangshaoyu.music_player.data_object.AlbumWithUserDo;
import com.wangshaoyu.music_player.data_object.TrackDo;
import com.wangshaoyu.music_player.repository.AlbumRepo;
import com.wangshaoyu.music_player.repository.RelationRepo;
import com.wangshaoyu.music_player.repository.TrackRepo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Controller
public class PublicController {
    private final TrackRepo trackRepo;
    private final AlbumRepo albumRepo;
    private final RelationRepo relationRepo;

    @Autowired
    public PublicController(TrackRepo trackRepo, AlbumRepo albumRepo, RelationRepo relationRepo) {
        this.trackRepo = trackRepo;
        this.albumRepo = albumRepo;
        this.relationRepo = relationRepo;
    }

    @GetMapping("/track")
    public ResponseEntity<byte[]> getTrack(int tid) {
        TrackDo trackDo = trackRepo.selectOneByTid(tid);
        log.debug("Get track(tid={}), {}, {}", tid, trackDo.type, trackDo.content.length);
        return ResponseEntity.ok()
                .contentType(MediaType.valueOf(trackDo.type))
                .body(trackDo.content);
    }

    static class AlbumView {
        public Integer aid;
        public String cover;
        public String title;
        public Integer uid;
        public String username;

        AlbumView(AlbumWithUserDo albumWithUserDo) {
            this.aid = albumWithUserDo.aid;
            this.cover = albumWithUserDo.cover;
            this.title = albumWithUserDo.title;
            this.uid = albumWithUserDo.uid;
            this.username = albumWithUserDo.username;
        }
    }

    static class AlbumListView {
        public List<AlbumView> albumList;
    }

    @GetMapping("/album-list.json")
    @ResponseBody
    public AlbumListView list() {
        List<AlbumWithUserDo> doList = albumRepo.selectListAllWithUser();
        AlbumListView view = new AlbumListView();
        view.albumList = new ArrayList<>();
        for (AlbumWithUserDo albumWithUserDo : doList) {
            AlbumView albumView = new AlbumView(albumWithUserDo);
            view.albumList.add(albumView);
        }

        return view;
    }

    @Data
    static class TrackView {
        public Integer tid;
        public String title;

        public TrackView(TrackDo trackDo) {
            this.tid = trackDo.tid;
            this.title = trackDo.title;
        }
    }

    @Data
    static class AlbumDetailView {
        public Integer aid;
        public String title;
        public String cover;
        public Integer uid;
        public String username;

        public List<TrackView> trackList;

        public void from(AlbumWithUserDo albumWithUserDo) {
            this.aid = albumWithUserDo.aid;
            this.title = albumWithUserDo.title;
            this.cover = albumWithUserDo.cover;
            this.uid = albumWithUserDo.uid;
            this.username = albumWithUserDo.username;
        }
    }

    @GetMapping("/album.json")
    @ResponseBody
    public AlbumDetailView detail(int aid) {
        AlbumDetailView view = new AlbumDetailView();
        AlbumWithUserDo albumWithUserDo = albumRepo.selectOneWithUserByAid(aid);
        if (albumWithUserDo == null) {
            log.error("aid 对应的专辑不存在");
            return view;
        }

        view.from(albumWithUserDo);

        List<Integer> tidList = relationRepo.selectTidListByAid(aid);
        List<TrackDo> trackDoList = trackRepo.selectListByTidList(tidList);
        view.trackList = new ArrayList<>();
        for (TrackDo trackDo : trackDoList) {
            TrackView trackView = new TrackView(trackDo);
            view.trackList.add(trackView);
        }

        return view;
    }
}
